package tpenchere.service;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
import org.omg.PortableServer.POAPackage.ServantNotActive;
import org.omg.PortableServer.POAPackage.WrongPolicy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
	private static Logger log = Logger.getLogger(Main.class);
	static String SERVICE_NAME = EnchereService.class.getName();

	static String GLASS = "glassfishorb.properties";
	static String JACORB = "jacorb.properties";
	static String SUN = "sunorb.properties";
	static String IUP = "iuporb.properties";

	// start orbd -ORBInitialPort 1050 -ORBInitialHost localhost

	/**
	 * @param args
	 * @throws IOException
	 * @throws InvalidName
	 * @throws AdapterInactive
	 * @throws WrongPolicy
	 * @throws ServantNotActive
	 * @throws org.omg.CosNaming.NamingContextPackage.InvalidName
	 * @throws CannotProceed
	 * @throws NotFound
	 */
	public void mains(String[] args) throws IOException, InvalidName,
			AdapterInactive, ServantNotActive, WrongPolicy,
			org.omg.CosNaming.NamingContextPackage.InvalidName, NotFound,
			CannotProceed {

		ApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "service-config.xml" });

		EnchereServiceImpl enchereServiceImpl = (EnchereServiceImpl) context
				.getBean("enchereServiceImpl");

		if (enchereServiceImpl == null)
			throw new IllegalStateException("serviceImpl NULL");

		String orbPropertyFile = IUP;
		// create and initialize the ORB
		log.info("loading orb.properties: " + orbPropertyFile);

		InputStream is = getClass().getResourceAsStream("/" + orbPropertyFile);
		log.info("input stream: " + is);
		Properties props = new Properties();
		props.load(is);

		log.info("launching orb with properties: " + props);

		ORB orb = ORB.init((String[]) null, props);
		// get reference to rootpoa & activate the POAManager
		POA rootpoa = POAHelper.narrow(orb
				.resolve_initial_references("RootPOA"));
		rootpoa.the_POAManager().activate();

		// create servant and register it with the ORB
		enchereServiceImpl.setORB(orb);
		log.info("service created");

		// get object reference from the servant
		org.omg.CORBA.Object ref = rootpoa
				.servant_to_reference(enchereServiceImpl);
		EnchereService href = EnchereServiceHelper.narrow(ref);
		log.info("invokes the name service");
		// get the root naming context
		// NameService invokes the name service
		org.omg.CORBA.Object objRef = orb
				.resolve_initial_references("NameService");

		// Use NamingContextExt which is part of the Interoperable
		// Naming Service (INS) specification.
		log.info("Use NamingContextExt");
		NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

		// bind the Object Reference in Naming
		NameComponent[] path = ncRef.to_name(SERVICE_NAME);
		log.info("service rebind");
		ncRef.rebind(path, href);

		log.info("EchoServer ready and waiting ...");
		orb.run();
	}

	/*
	 * Static class cannot do getClass()
	 */
	public static void main(String[] args) throws Exception {
		new Main().mains(args);
	}

}
